#include "udf_global.h"

#if ( UDF_EN_09 > 0 && !defined(UDP_SUB_PROJECT) && !defined(UDT_SUB_PROJECT) && (defined(UDF09_SUB_PROJECT) || defined(UDF_PRJ)) )

#include "udsf.h"

#include "../udsf/udsf_udf_switch.c"
#include "../udsf/udsf_delay.c"

void UDF09_udf_handle(void){
	
	// close wdt
	NVIC->ICER[0] = (1 << ((uint32_t)(WDT_IRQn) & 0x1F));
	SYSC->CLK_EN &= ~WDT_PATTERN_EN_Msk;
	SYSC->CLK_EN |= (WDT_PATTERN_EN_Msk&(WDT_PATTERN_DISABLE<<WDT_PATTERN_EN_Pos)); // Close WDT clock 		
	
  sUDF_global.ota_status = OTA_STATUS_IDLE;
	
	udsf_uart_send_string("[OTA Demo]: STARTUP@AREA-");
	if( paramFunc->ab_area_flag == 1 ){
		udsf_uart_send_string("A\n");
	}else if( paramFunc->ab_area_flag == 2 ){
		udsf_uart_send_string("B\n");
	}else{
		udsf_uart_send_string("UNKNOWN\n");
	}

	//?: ? Demo ???UART-OTA
	udsf_delay_ms(1500);
	udsf_uart_send_string("[OTA Demo]: RUNNING...\n");

	udsf_uart_recv_init();
		
	uint8_t recv_data[50];
	
	uint32_t download_addr = BBE_ABUF0_BASE;
	
	while(1){
		
		if( sUDF_global.ota_status == OTA_STATUS_IDLE ){
			int len;
			len = udsf_uart_recv_frame_data(recv_data,sizeof(recv_data));
			if( len > 0 ){
				//udsf_uart_send_data(recv_data,len);
				if( udsf_strstr((char*)recv_data,"MCU START") > 0 ){
					if( paramFunc->ab_area_flag == 1 ){
						udsf_uart_send_string("[OTA Demo]: OTA START_A...\n");
					}else{
						udsf_uart_send_string("[OTA Demo]: OTA START_B...\n");
					}
					
					//??XIP/ROM??,???????????????????
					udsf_uart_recv_disable();
					
					sUDF_global.ota_status = OTA_STATUS_DOWNLOAD;
				}else if(udsf_strstr((char*)recv_data,"MIND OTA") > 0){
					udsf_delay_ms(1000);
          udsf_uart_send_string("MIND OTA START...\n"); 
 					udsf_uart_recv_disable();
//        udsf_spiflash_erase_sector(UDK_MIND_OTA_START_ADDR); //flash模拟测试，读数时高位在后，低位在前
//				uint8_t test_data[256] ;
//				for(int i = 0;i<256;i++)
//				{
//				test_data[i]=0xA6;
//				}
//				for(int sCnt=0;sCnt<40;sCnt++)
//				{
//				udsf_memcpy(test_data,(uint8_t*)download_addr+22*1024+sCnt*256,256);
//				}
//				udsf_memory_program(UDK_MIND_OTA_START_ADDR,\
//				p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,(uint8_t*)(download_addr+22*1024),10*1024);  //后面存灵动微升级包，放在160K起始   
//        test_data[0] = 0x8;
//        test_data[1] = 0xFF;
//        test_data[2] = 0xFF;
//        test_data[3] = 0xFF;
//        test_data[4] = 0x1;
//        test_data[5] = 0x2;
//        test_data[6] = 0x3;
//        test_data[7] = 0x4;
//        test_data[8] = 0x05;
//        test_data[9] = 0x2B;
//        test_data[10] = 0x0;
//        test_data[11] = 0x0;
//        test_data[12] = 0x2C;
//        test_data[13] = 0x00;
//        test_data[14] = 0x00;
//        test_data[15] = 0x00;
//        udsf_spiflash_write_data(&test_data[0],UDK_MIND_OTA_START_ADDR,16);          
          
					sUDF_global.ota_status = OTA_MIND_TRANSMISSION;         
        }
			}
		}else{
			if( sUDF_global.ota_status == OTA_STATUS_DOWNLOAD ){

				#if OTA_SIZE_MAX > BBE_SRAM_SIZE // ?demo ??? ??40KB OTA???
				#error OTA_SIZE_MAX > BBE_SRAM_SIZE
				#endif
				
				/* ???????,??OTA?????????? */
				#if defined(FAKE_RECV) // fake download. copy current area -> sram(BBE 40K)
				udsf_uart_send_string("[OTA Demo]: FAKE RECV...\n");
				
				// ?????? BBE_SRAM
				udsf_memory_load2sram(USRBOOT_UDP_DEFAULT_OFFSET+(paramFunc->ab_area_flag-1)*OTA_SIZE_MAX,p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,\
				(uint8_t*)download_addr,OTA_SIZE_MAX);
				
				sUDF_global.ota_status = OTA_STATUS_OTA_WRITE;
				sUDF_global.ota_len = OTA_SIZE_MAX;
				#else
				// demo uart-ota
				uint8_t* pData8    = (uint8_t *)(sUDF_global.recv_buff);
				
				int page_cnt = 0;
				
				while(1){
					for(int sCnt=0;sCnt<PAGE_PACK_LEN;sCnt++){
						while((USCI1->ISR & USCI_ISR_RXNE_Msk)==0);
							pData8[sCnt]=USCI1->TRX;
//							WDT->STR = 1;
					}
					
					
					if( (pData8[0] == 'A') && (pData8[1] == 'T') && (pData8[2] == '+') &&
						  (pData8[3] == 'C') && (pData8[4] == 'R') && (pData8[5] == 'C') ){
						//printf("CRC = %x\r\n",udsf_get_crc((uint8_t*)download_addr,(pData8[3+11]<<24) | (pData8[2+11]<<16) | (pData8[1+11]<<8) | pData8[0+11]));
						uint16_t crc = 1;
						for(int sCnt=17;sCnt<PAGE_PACK_LEN;sCnt++){
							if( pData8[sCnt] != 0xA5 ){
								crc = 0;
							}
						}
						if( crc == 1 ){
							
							uint32_t len = (pData8[3+11]<<24) | (pData8[2+11]<<16) | (pData8[1+11]<<8) | pData8[0+11];
							
							if( len <= BBE_SRAM_SIZE ){
								crc = pData8[1+15]<<8 | pData8[0+15];

								uint16_t Crc16 = udsf_get_crc((uint8_t*)download_addr,len);

								if( Crc16 == crc ){
									udsf_uart_send_string("AT+CRC=OK\n");	
									sUDF_global.ota_status = OTA_STATUS_OTA_WRITE;
									sUDF_global.ota_len = len;
									udsf_delay_ms(20);
									break;
								}else{
									udsf_uart_send_string("AT+CRC=ERR\n");
									//20240530 wz
									WDT_RSTNOW();
									while(1);
								}
							}else{
								udsf_uart_send_string("AT+CRC=ERR\n");
									//20240530 wz
									WDT_RSTNOW();
								while(1);
							}
						}
					}

					udsf_memcpy(pData8,(uint8_t*)download_addr+PAGE_PACK_LEN*page_cnt,PAGE_PACK_LEN);
					
//					printf("page_cnt = %d\r\n",page_cnt);
//					udsf_uart_send_data(pData8,6);
//					if(page_cnt == 88){
//						udsf_uart_send_data(pData8,256);
//					}
					page_cnt++;
					udsf_uart_send_string("AT+OK\n");
					
				}
				#endif
			}else if( sUDF_global.ota_status == OTA_STATUS_OTA_WRITE ){
				udsf_uart_send_string("[OTA Demo]: WRITE OTA...\n");
				
				// ??ota??? ?????
				uint32_t start_addr = USRBOOT_UDP_DEFAULT_OFFSET+(2-paramFunc->ab_area_flag)*OTA_SIZE_MAX;
				uint32_t len_RCS = 22*1024;
        uint32_t len_MIND =sUDF_global.ota_len - 22*1024;
				udsf_memory_program(start_addr,\
				p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,(uint8_t*)(download_addr),len_RCS);//前22K存2412升级包
 				udsf_memory_program(UDK_MIND_OTA_START_ADDR,\
				p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,(uint8_t*)(download_addr+22*1024),len_MIND);  //后面存灵动微升级包，放在160K起始   
               
				sUDF_global.ota_status = OTA_STATUS_INFO_WRITE;
			}else if( sUDF_global.ota_status == OTA_STATUS_INFO_WRITE ){
				udsf_uart_send_string("[OTA Demo]: WRITE INFO...\n");
				uint32_t sn;
				uint32_t sn_bu;
				// ??????? sn@INFO
				udsf_memory_load2sram(USRBOOT_INFO_OFFSET+(paramFunc->ab_area_flag-1)*USRBOOT_INFO_SIZE_PRE+UDP_SIZE,p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,\
				(uint8_t*)&sn,4);
				udsf_memory_load2sram(USRBOOT_INFO_OFFSET+(paramFunc->ab_area_flag-1)*USRBOOT_INFO_SIZE_PRE+UDP_SIZE+4,p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,\
				(uint8_t*)&sn_bu,4);
				
				if( sn+sn_bu != 0xffffffff ){
					sn = 0; // ??????INFO???(??OTA ??INFO????)
				}
				// sn+1
				sn += 1;
				*(uint32_t*)(download_addr+UDP_SIZE)   = sn;
				*(uint32_t*)(download_addr+UDP_SIZE+4) = 0xffffffff - sn;
				
				// ???? INFO
				udsf_memory_program(USRBOOT_INFO_OFFSET+(2-paramFunc->ab_area_flag)*USRBOOT_INFO_SIZE_PRE,\
				p_gb_sysboot->boot_flag,p_gb_sysboot->udt_src,(uint8_t*)(download_addr),FLASH_SECTOR_SIZE);
				
				udsf_uart_send_string("[OTA Demo]: WILL RESET...\n");
				WDT_RSTNOW();
				while(1);
			}else if( sUDF_global.ota_status == OTA_MIND_TRANSMISSION)
      {       
        udsf_spiflash_read_data((uint8_t*)(download_addr),UDK_MIND_OTA_START_ADDR,16*1024);
				
//       udsf_uart_send_string("MIND CNT ONE...\n");
//        udsf_uart_send_data ( (uint8_t*)download_addr,16 );
//        sUDF_global.mind_CRC8 = Read_M8(download_addr+12);
//        sUDF_global.mind_CRC32 = Read_M32(download_addr+8);
        sUDF_global.mind_len = Read_M32(download_addr);//经过实验，只能偏移4的倍数
        sUDF_global.mind_pack = Read_M32(download_addr+4);
			
//        udsf_uart_send_string("MIND CNT TWO...\n")
//        printf("pack = %d,len = %d\n" ,sUDF_global.mind_pack,sUDF_global.mind_len);
        sUDF_global.ota_status = 5;        

      }else if( sUDF_global.ota_status == 5)
      {
        uint8_t* pData8    = (uint8_t *)(sUDF_global.recv_buff);
//        udsf_uart_send_string("MIND OTA READY...\r\n  ");        
        for(int sCnt=0;sCnt<8;sCnt++){
						while((USCI1->ISR & USCI_ISR_RXNE_Msk)==0);
							pData8[sCnt]=USCI1->TRX;
//							WDT->STR = 1;
					}

 					if( (pData8[0] == 0x01) && (pData8[1] == 0x02) && (pData8[2] == 0x03) &&
						  (pData8[3] == 0x04) && (pData8[4] == 0x05) )       
        {
//          udsf_uart_send_string("MIND OTA OK...\r\n  ");      
          uint8_t back_cnt = pData8[5];
          uint16_t back_len = (pData8[6]<<8) + pData8[7];
          uint16_t last_back = sUDF_global.mind_len - (sUDF_global.mind_pack - 1)*back_len;
          
          if(back_cnt == 0)
          {
            udsf_uart_send_data ( (uint8_t*)download_addr,16 );
          }
          else if(back_cnt ==sUDF_global.mind_pack )
          {
            udsf_uart_send_data ( (uint8_t*)download_addr+16+back_len*(sUDF_global.mind_pack-1),last_back);
          }
          else if(back_cnt<sUDF_global.mind_pack)
          {
            udsf_uart_send_data ( (uint8_t*)download_addr+16+back_len*(back_cnt-1),back_len);
          }
          else
          {
            udsf_uart_send_string("OTA CNT ERR...\r\n  "); 
          }
        
        }
				else 
//					udsf_uart_send_data(pData8,8);
         	if( (pData8[0] == 0x08) && (pData8[1] == 0x07) && (pData8[2] == 0x06) &&
						  (pData8[3] == 0x05) && (pData8[4] == 0x04) ) 
          {
//            udsf_uart_send_data(pData8,8);
						
						udsf_uart_send_string("MIND OTA FINISH...\r\n  "); 
						udsf_delay_ms (10);
            WDT_RSTNOW();
			     	while(1);
          }
        
        
       
      }
		}
	}	
//		udsf_udf_switch_without_crc(3,9); // udf09->udf03
		//break;			
}
#endif
